package com.lzy.crm.wechat.controller;

import java.io.StringReader;
import java.security.PublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xml.sax.InputSource;

import com.google.gson.JsonObject;
import com.lzy.crm.base.date.DateUtil;
import com.lzy.crm.base.util.CommonUtil;
import com.lzy.crm.base.util.JsonUtil;
import com.lzy.crm.base.util.StringUtil;
import com.lzy.crm.domain.BankCard;
import com.lzy.crm.domain.PpUser;
import com.lzy.crm.domain.TradeFlow;
import com.lzy.crm.service.BankCardService;
import com.lzy.crm.service.PpUserService;
import com.lzy.crm.service.TradeFlowService;
import com.lzy.crm.util.BootJsonResponse;
import com.lzy.crm.util.RSAUtil;
import com.lzy.crm.util.XmlUtil;
import com.lzy.crm.wechat.consts.WechatPayProperties;
import com.lzy.crm.wechat.util.Base64;
import com.lzy.crm.wechat.util.GetPublicKey;
import com.lzy.crm.wechat.util.GetRSA;
import com.lzy.crm.wechat.util.HttpClientCustomSSL;
import com.lzy.crm.wechat.util.HttpUtils;
import com.lzy.crm.wechat.util.PayUtil;
import com.lzy.crm.wechat.util.RandomUtil;
import com.lzy.crm.wechat.util.WeixinUtil;
import com.lzy.crm.wechat.util.XMLUtils;


/**
 * 银行体现控制器
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/gm")
public class GmTradeFlowController {
	
	
	Logger LOG = Logger.getLogger(GmTradeFlowController.class);
	
	private static final String TRANSFERS_PAY = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 企业付款

	private static final String TRANSFERS_PAY_QUERY = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo"; // 企业付款查询

	private static final String APP_ID = WechatPayProperties.getAppId();  //ConfigUtil.getProperty("wx.appid");

	private static final String MCH_ID = WechatPayProperties.getPartnerId(); // ConfigUtil.getProperty("wx.mchid");

	private static final String API_SECRET =WechatPayProperties.getPartnerKey() ;//WechatPayProperties.getAppSecret();// ConfigUtil.getProperty("wx.api.secret");
	
	
	@Resource
	private BankCardService bankCardService;
	
	@Resource
	private PpUserService pUserService;
	
	
	@Resource
	TradeFlowService tradeFlowService;
	
	
	/**
	 * 企业向个人支付转账
	 * @param request
	 * @param response
	 * @param openid 用户openid
	 * @param callback
	 */
	@RequestMapping(path="/tx_pay",method=RequestMethod.POST,produces="text/html;charset=UTF-8")
	@ResponseBody
	public String transferPay(HttpServletRequest request, HttpServletResponse httpresponse, String openid, String callback) {
		LOG.info("[/transfer/pay]");
		BootJsonResponse response=new BootJsonResponse();
		
		String money = request.getParameter("money");
		
		
		Integer tixianMoney =Integer.parseInt(money);
		
		//业务判断 openid是否有收款资格
		PpUser user =(PpUser)request.getSession().getAttribute("userSession");
		
		
		PpUser newUser = pUserService.getPpUser(user.getUid()+"");
		
		// 检验今天是否已体现
	    Date date =new Date();
		String startDate = DateUtil.formatDateWithoutTime(date)+" 00:00:00";
		String endDate = DateUtil.formatDateWithoutTime(date)+" 23:59:59";
	    List<TradeFlow> tradeFlowList = tradeFlowService.getTradeFlow(user.getUid(), startDate, endDate);
	    if(tradeFlowList!=null&&tradeFlowList.size()>0){
	    	response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage(" 每天只可提现一次 ~ ");
			return JsonUtil.toJson(response);
	    }
	    
	    
	    if(newUser.getBackgold()<tixianMoney){
	    	response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage(" 已大于可提现金额 ~ ");
			return JsonUtil.toJson(response);
	    }
	    
	    if(newUser.getBackgold()<1){
	    	response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage("提现金额大于1元 ，才可提现~");
			return JsonUtil.toJson(response);
	    }
	    
		Map<String, String> restmap = null;
		try {
			Map<String, Object> parm = new HashMap<String, Object>();
			parm.put("mch_appid", APP_ID); //公众账号appid
			parm.put("mchid", MCH_ID); //商户号
			parm.put("nonce_str", PayUtil.getNonceStr()); //随机字符串
			parm.put("partner_trade_no",PayUtil.getTransferNo()); //商户订单号
			parm.put("openid", user.getOpenid()); //用户openid	
			parm.put("check_name", "NO_CHECK"); //校验用户姓名选项 OPTION_CHECK
			//parm.put("re_user_name", "yy"); //check_name设置为FORCE_CHECK或OPTION_CHECK，则必填
			parm.put("amount", tixianMoney); //转账金额
			parm.put("desc", "测试转账到个人"); //企业付款描述信息
			parm.put("spbill_create_ip", PayUtil.getLocalIp(request)); //Ip地址
			parm.put("sign", PayUtil.getSign(parm, API_SECRET));

			String restxml = HttpUtils.posts(TRANSFERS_PAY, XmlUtil.xmlFormat(parm, false));
			System.out.println(restxml);
			restmap = XmlUtil.xmlParse(restxml);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}

		if (CommonUtil.isNotEmpty(restmap) && "SUCCESS".equals(restmap.get("result_code"))) {
			LOG.info("转账成功：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
			Map<String, String> transferMap = new HashMap<>();
			transferMap.put("partner_trade_no", restmap.get("partner_trade_no"));//商户转账订单号
			transferMap.put("payment_no", restmap.get("payment_no")); //微信订单号
			transferMap.put("payment_time", restmap.get("payment_time")); //微信支付成功时间
			/*WebUtil.response(response,
					WebUtil.packJsonp(callback,
							JSON.toJSONString(new JsonResult(1, "转账成功", new ResponseData(null, transferMap)),
									SerializerFeatureUtil.FEATURES)));*/
			response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage("提现已受理~");
		}else {
			if (CommonUtil.isNotEmpty(restmap)) {
				LOG.info("转账失败：" + restmap.get("err_code") + ":" + restmap.get("err_code_des"));
			}
			/*WebUtil.response(response, WebUtil.packJsonp(callback, JSON
					.toJSONString(new JsonResult(-1, "转账失败", new ResponseData()), SerializerFeatureUtil.FEATURES)));*/
			response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage("提现金失败~");
		}
		
		return JsonUtil.toJson(response);
	}
	

	
	/**
	 * 企业向个人银行帐号转账
	 * @param request
	 * @param response
	 * @param openid 用户openid
	 * @param callback
	 * @throws Exception 
	 */
	@RequestMapping(path="/tx_bank_pay",method=RequestMethod.POST,produces="text/html;charset=UTF-8")
	@ResponseBody
	public String tx_bank_pay(HttpServletRequest request, HttpServletResponse httpResponse ) throws Exception {
		BootJsonResponse response=new BootJsonResponse();
		LOG.info("[/transfer/pay]");
		//业务判断 openid是否有收款资格
		PpUser user =(PpUser)request.getSession().getAttribute("userSession");
		
		String money = request.getParameter("money");
		
		Integer tixianMoney =Integer.parseInt(money);
		// TODO Auto-generated method stub
		String amount = String.valueOf(tixianMoney*100);
		
	    String desc =" 银行卡提现 ";
	    String partner_trade_no = WeixinUtil.getTimeStamp()+ WeixinUtil.getNonceStr(); //"20171124331gang2333311";
		
	    PpUser newUser = pUserService.getPpUser(user.getUid()+"");
	    
	    // 检验今天是否已体现
	    Date date =new Date();
		String startDate = DateUtil.formatDateWithoutTime(date)+" 00:00:00";
		String endDate = DateUtil.formatDateWithoutTime(date)+" 23:59:59";
	    List<TradeFlow> tradeFlowList = tradeFlowService.getTradeFlow(user.getUid(), startDate, endDate);
	    if(tradeFlowList!=null&&tradeFlowList.size()>0){
	    	response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage(" 每天只可提现一次 ~ ");
			return JsonUtil.toJson(response);
	    }
	    
	    
	    if(newUser.getBackgold()<tixianMoney){
	    	response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage(" 已大于可提现金额 ~ ");
			return JsonUtil.toJson(response);
	    }
	    
	    if(1>=tixianMoney){
	    	response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage(" 提现金额必须大于1元 ~ ");
			return JsonUtil.toJson(response);
	    }
	    
	    
	    if(newUser.getBackgold()<1){
	    	response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage("提现金额大于1元 ，才可提现~");
			return JsonUtil.toJson(response);
	    }
	    
		//校验
	    List<BankCard> bankCardList =bankCardService.getBankCardListByUserId(user.getUid()+"");
		if(bankCardList.size()<1){
			response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage("请填写银行卡信息~");
			return JsonUtil.toJson(response);
		}
		BankCard bankCard = bankCardList.get(0);
		
		String source =bankCard.getBankUserName();
		String pank = bankCard.getBankUserNo();
		String bank_code = bankCard.getBankName();
		
		if(bank_code.length()!=4){
			response.setStatusCode(BootJsonResponse.STATUS_CODE_FAILURE);
			response.setMessage("银行卡 信息有误~ ");
			return JsonUtil.toJson(response);
		}
		
		
		TradeFlow tradeFlow= new TradeFlow();
		tradeFlow.setUid(user.getUid());
		tradeFlow.setPartnerTradeNo(partner_trade_no);
		tradeFlow.setAmount(tixianMoney.doubleValue());
		tradeFlow.setBankName(bank_code);
		tradeFlow.setBankUserName(source);
		tradeFlow.setBankUserNo(pank);
		tradeFlow.setStatus("0");
		tradeFlow.setCreateUserId(user.getUid());
		tradeFlow.setCreateTime(new Date());
		tradeFlowService.insertSelective(tradeFlow);
		
		String keyfile = "E:/cert/public.pem"; //读取PKCS8密钥文件
		//RSA工具类提供了，根据加载PKCS8密钥文件的方法
		PublicKey pub=RSAUtil.getPubKey(keyfile,"RSA"); 
		
        String rsa ="RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING";
        byte[] estr=RSAUtil.encrypt(pank.getBytes(),pub,2048, 11,rsa);   //对银行账号进行加密
        String enc_bank_no =Base64.encode(estr);//并转为base64格式
		
        estr=RSAUtil.encrypt(source.getBytes("UTF-8"),pub,2048, 11,rsa);   //对银行账号进行加密
        String enc_true_name =Base64.encode(estr);//并转为base64格式
		
		//注意 这里的  publicKeyPKCS8  是上一步获取微信支付公钥后经openssl 转化成PKCS8格式的公钥
		//String publicKeyPKCS8 =pub.getEncoded();
		//System.out.println("publicKeyPKCS8" + publicKeyPKCS8);
		//String enc_true_name =GetRSA.getRSA(source,publicKeyPKCS8);
		//String enc_bank_no = GetRSA.getRSA(pank,publicKeyPKCS8);
	    
	    String nonce_str1 = RandomUtil.randomString(RandomUtil.LETTER_NUMBER_CHAR, 28);// StringUtils.getStrRandom(28);
	    //获取签名
	    SortedMap<Object,Object> parameters1 = new TreeMap<Object,Object>();
		parameters1.put("mch_id", MCH_ID );
		parameters1.put("partner_trade_no", partner_trade_no);
		parameters1.put("nonce_str", nonce_str1);
		parameters1.put("enc_bank_no", enc_bank_no);
		parameters1.put("enc_true_name", enc_true_name);
		parameters1.put("bank_code", bank_code);
		parameters1.put("amount", amount);
		parameters1.put("desc", desc);
		String sign1 = PayUtil.creatSign("UTF-8", parameters1 , API_SECRET);
		
		//请求企业付款
		TreeMap<String, String> tmap1 = new TreeMap<String, String>();
		 tmap1.put("mch_id", MCH_ID);
		 tmap1.put("partner_trade_no", partner_trade_no);
		 tmap1.put("nonce_str", nonce_str1);
		 tmap1.put("enc_bank_no", enc_bank_no);
		 tmap1.put("enc_true_name", enc_true_name);
		 tmap1.put("bank_code", bank_code);
		 tmap1.put("amount", amount);
		 tmap1.put("desc", desc);
		 tmap1.put("sign", sign1);
		String xml2 = XMLUtils.getRequestXml(tmap1);
		System.out.println("xm12--: "+xml2);
		String  xml3= HttpClientCustomSSL.httpClientResultPANK(xml2);
		LOG.error("提现信息："+xml3);
		
		StringReader sr = new StringReader(xml3);
		InputSource is = new InputSource(sr);
		Document doc = (new SAXBuilder()).build(is);
		Element root = doc.getRootElement();
		
		if(StringUtil.equals(root.getChild("result_code").getText(), "SUCCESS")){
			// 执行成功处理
			tradeFlow.setStatus("1");
			tradeFlow.setPaymentNo(root.getChild("payment_no").getText());
			tradeFlow.setRemark(root.getChild("err_code_des").getText());
			tradeFlowService.updateByPrimaryKeySelective(tradeFlow);
			Double totel = newUser.getBackgold() - tixianMoney;
			newUser.setBackgold(totel);
			pUserService.updateByPrimaryKeySelective(newUser);
			user.setBackgold(totel);
			response.setStatusCode(BootJsonResponse.STATUS_CODE_SUCCESS);
			response.setMessage("提现已受理~");
		}else{
			
			tradeFlow.setStatus("2");
			tradeFlow.setRemark(root.getChild("err_code_des").getText());
			tradeFlowService.updateByPrimaryKeySelective(tradeFlow);
			
			response.setStatusCode(BootJsonResponse.STATUS_CODE_SUCCESS);
			response.setMessage("提现失败，请联系管理员~");
		}
		
		return JsonUtil.toJson(response); 
	}
	
	
	
	
	
	
	
	
	

}
